package utils

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"encoding/pem"
	"fmt"
	"os"
)

/*
公钥：
密钥：
*/

// 保存生成的公钥和密钥
func SaveRsaKey(bits int) error {

	private, err := rsa.GenerateKey(rand.Reader, bits)
	fmt.Println(private)
	fmt.Println(err)

	if err != nil {
		return err
	}

	publicKey := private.PublicKey

	//使用 x509 标准进行编码  AsN,1 编码字符串
	x509_Private := x509.MarshalPKCS1PrivateKey(private)
	// 使用x509标准对公钥进行编码， AsN.1编码字符串
	x509_public := x509.MarshalPKCS1PublicKey(&publicKey)

	fmt.Println(x509_Private)
	fmt.Println(x509_public)
	// 对私钥进行封装 block 结构数据
	block_private := pem.Block{Type: "private key", Bytes: x509_Private}
	// 对公钥进行封装 block 结构数据
	block_public := pem.Block{Type: "public key", Bytes: x509_public}

	// 存放私钥的文件
	privateFile, err_pri := os.Create("privateKey.pem")
	if err_pri != nil {
		return err_pri
	}
	defer privateFile.Close()
	pem.Encode(privateFile, &block_private)
	// 存放公钥的文件
	publicFile, err_pub := os.Create("publicKey.pem")
	if err_pub != nil {
		return err_pub
	}
	defer publicFile.Close()
	pem.Encode(publicFile, &block_public)
	return nil
}

// 加密
func RsaEncode(src, file_path string) ([]byte, error) {
	src_byte := []byte(src)
	// 读文件
	file, err := os.Open(file_path)
	if err != nil {
		return src_byte, err
	}

	file_info, err_info := file.Stat()
	if err_info != nil {
		return src_byte, err_info
	}
	// 读取文件
	key_bytes := make([]byte, file_info.Size())
	//读取内容到容器里面
	file.Read(key_bytes)

	// pem 解码
	block, _ := pem.Decode(key_bytes)

	//x509解码
	public_Key, err_pb := x509.ParsePKCS1PublicKey(block.Bytes)
	if err_pb != nil {
		return src_byte, err_pb
	}
	fmt.Println(public_Key)

	// 使用公钥对铭文进行加密
	ret_byte, err_ret := rsa.EncryptPKCS1v15(rand.Reader, public_Key, src_byte)
	if err_ret != nil {
		return src_byte, err_ret
	}
	//fmt.Println(ret_byte)
	return ret_byte, nil
}

// 解密
func RsaDecode(src_byte []byte, file_path string) ([]byte, error) {

	// 读文件
	file, err := os.Open(file_path)
	if err != nil {
		return src_byte, err
	}

	file_info, err_info := file.Stat()
	if err_info != nil {
		return src_byte, err_info
	}
	// 读取文件
	key_bytes := make([]byte, file_info.Size())
	//读取内容到容器里面
	file.Read(key_bytes)

	// pem 解码
	block, _ := pem.Decode(key_bytes)

	//x509解码
	privateKey, err_pb := x509.ParsePKCS1PrivateKey(block.Bytes)
	if err_pb != nil {
		return src_byte, err_pb
	}

	// 进行解码
	ret_byte, err_ret := rsa.DecryptPKCS1v15(rand.Reader, privateKey, src_byte)
	if err_ret != nil {
		return src_byte, err_ret
	}

	return ret_byte, nil
}
